package cn.mason.pandabi.fileservice;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@SpringBootApplication
@EnableEurekaClient
@RestController
public class FileServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(FileServiceApplication.class, args);
	}
	private Logger logger= LoggerFactory.getLogger(this.getClass());
	private final String RESOURCE_PATH="service-file/src/main/resources/static/files";
	private final String PORT="8096";
	private final String HOST="http://localhost:";

	@Value("${server.port}")
	private String port;

	@RequestMapping(value = "/")
	public String index(){
		return "file-service";
	}

	/**
	 * 上传文件
	 * @param file
	 * @param filepath
	 * @return
	 */
	@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file,
											  @RequestParam("filepath") String filepath){
		String filename=file.getOriginalFilename();
		try {
			File targetFilePath=new File(this.RESOURCE_PATH+filepath);
			if(!targetFilePath.exists()){
				targetFilePath.mkdirs();
			}
			File file1=new File(targetFilePath+"/"+filename);
			file1.createNewFile();
			FileOutputStream fileOutputStream=new FileOutputStream(file1);
			fileOutputStream.write(file.getBytes());
			fileOutputStream.flush();
			fileOutputStream.close();
			return ResponseEntity.status(HttpStatus.OK).body(this.HOST+this.PORT+"/files"+filepath+"/"+filename+port);
		}catch (UnknownHostException uhe){
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
		}catch (IOException ioe){
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
		}
	}

	/**
	 * 下载文件
	 * @param file
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/downFile",method = RequestMethod.GET)
	public void downFile(@RequestParam("file") String file, HttpServletRequest request, HttpServletResponse response)throws IOException {
		File file1 = new File(RESOURCE_PATH + file);
		if (file1.exists()) {
			request.setCharacterEncoding("UTF-8");
			response.setContentType("application/force-download");//应用程序强制下载
			InputStream in = new FileInputStream(file1);
			response.setHeader("Content-Disposition", "attachment;filename=" + file);
			response.setContentLength(in.available());
			OutputStream out = response.getOutputStream();
			byte[] b = new byte[1024];
			int len = 0;
			while ((len = in.read(b)) != -1) {
				out.write(b, 0, len);
			}
			out.flush();
			out.close();
			in.close();
		}
	}

    /**
     * 将JSON转成EXCEL
     * @param response
     * @return
     */
	@RequestMapping(value = "/jsonToExcel",method = RequestMethod.POST)
	public void  jsonToExcel(HttpServletResponse response,@RequestParam("jsonFile")MultipartFile jsonFile)throws IOException{
		InputStream is=jsonFile.getInputStream();
		BufferedReader reader=new BufferedReader(new InputStreamReader(is));
		StringBuffer sb=new StringBuffer();
		String line = reader.readLine(); // 读取第一行
		while(line!=null){
			sb.append(line);
			sb.append("\n");
			line=reader.readLine();
		}
		reader.close();
		is.close();

		JSONArray jsonArray=JSONArray.fromObject(sb.toString());
		JSONObject jsonObject=JSONObject.fromObject(jsonArray.get(0));
		int rows=jsonArray.size();
		int cols=jsonObject.size();

		XSSFWorkbook wb = new XSSFWorkbook();
		XSSFSheet sheet = wb.createSheet("数据");
		XSSFRow row = sheet.createRow(0);
		XSSFCellStyle style = wb.createCellStyle();

		Iterator iterator=jsonObject.keys();
		List<String> titles=new ArrayList<String>();
		int col=0;
		while (iterator.hasNext()){
			Object o=iterator.next();
			XSSFCell cell = row.createCell(col++); //第一个单元格
			titles.add(o.toString());
			cell.setCellValue(o.toString());
			cell.setCellStyle(style);
		}

		for (int i = 0; i < rows; i++) {
			row = sheet.createRow(i+1);
			JSONObject jo=jsonArray.getJSONObject(i);
			for(int j=0;j<cols;j++){
				row.createCell(j).setCellValue(jo.get(titles.get(j)).toString());
			}
		}

		FileOutputStream fout = new FileOutputStream("temp.xlsx");
		wb.write(fout);
		fout.close();

		File file=new File("temp.xlsx");
		String filename = file.getName();
		InputStream fis = new BufferedInputStream(new FileInputStream("temp.xlsx"));
		byte[] buffer = new byte[fis.available()];
		fis.read(buffer);
		fis.close();
		response.reset();
		response.setContentType("application/x-msdownload");
		response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
		response.addHeader("Content-Length", "" + file.length());
		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("application/octet-stream");
		toClient.write(buffer);
		toClient.flush();
		toClient.close();
		file.delete();
	}

	/**
	 * 将EXCEL转成JSON
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/excelToJson",method = RequestMethod.POST)
	public void excelToJson(HttpServletResponse response, @RequestParam("excelFile")MultipartFile excelFile)throws IOException{
		File temp=new File("temp.xlsx");
		JSONArray result=new JSONArray();
		List<String> title=new ArrayList<>();

		try {
			temp.createNewFile();
			FileOutputStream fileOutputStream=new FileOutputStream(temp);
			fileOutputStream.write(excelFile.getBytes());
			fileOutputStream.flush();
			fileOutputStream.close();
			XSSFWorkbook wb=new XSSFWorkbook(new FileInputStream(temp));
			XSSFSheet sheet0=wb.getSheetAt(0);
			XSSFRow row0=sheet0.getRow(0);

			//确认元素名称，第一行必须是名称，而不是数据
			for(int i=0;i<row0.getPhysicalNumberOfCells();i++){
				XSSFCell cell=(XSSFCell)row0.getCell(i);
				title.add(cell.toString());
			}
			logger.info(""+sheet0.getLastRowNum());
			for(int i=1;i<=sheet0.getLastRowNum();i++){
				XSSFRow row=(XSSFRow) sheet0.getRow(i);
				JSONObject o=new JSONObject();
				int length=row0.getPhysicalNumberOfCells();
				for (int j=0;j<length;j++)
				{
					XSSFCell cell=(XSSFCell) row.getCell(j);
					if(cell!=null){
						String value=cell.toString();
						o.element(title.get(j),value);
					}
				}
				result.add(o);
			}
			temp.delete();
		}catch (IOException e){
			logger.error(e.getMessage());
			e.printStackTrace();
		}catch (OfficeXmlFileException e){
			logger.error(e.getMessage());
			e.printStackTrace();
		}

		File jsonFile=new File(excelFile.getOriginalFilename().split("\\.")[0]+".json");
		FileOutputStream fileOutputStream=new FileOutputStream(jsonFile);
		fileOutputStream.write(result.toString().getBytes());
		fileOutputStream.close();

		response.reset();
		response.setContentType("application/x-msdownload");
		response.addHeader("Content-Disposition", "attachment;filename=" + new String(jsonFile.getName().getBytes()));
		response.addHeader("Content-Length", "" + jsonFile.length());
		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("application/octet-stream");
		toClient.write(result.toString().getBytes());
		toClient.flush();
		toClient.close();
		jsonFile.delete();
	}
}
